[Pytorch练手]使用CNN图像分类
需求
在4*4的图片中,比较外围黑色像素点和内圈黑色像素点个数的大小将图片分类
如上图图片外围黑色像素点5个大于内圈黑色像素点1个分为0类反之1类
想法
- 通过numpy、PIL构造4*4的图像数据集
- 构造自己的数据集类
- 读取数据集对数据集选取减少偏斜
- cnn设计因为特征少,直接1*1卷积层
- 或者在4*4外围添加padding成6*6,设计2*2的卷积核得出3*3再接上全连接层
代码
1 | import torch |
构造数据集
1 | import csv |
1 | root=r'/Users/null/Documents/PythonProject/Classifier' |
构造训练数据集
1 | buildDataset(root,'train',20000) |
构造测试数据集
1 | buildDataset(root,'test',10000) |
读取数据集
1 | class MyDataset(torch.utils.data.Dataset): |
1 | trainData=MyDataset(root = root,datacsv='trainDataInfo.csv', transform=transforms.ToTensor()) |
处理数据集使得数据集不偏斜
1 | import itertools |
1 | scale = 4 |
(2250, 1122)
1 | import torch.utils.data as Data |
定义模型
1 | from torch import nn |
1 | class Net(Module): |
1 | class Net2(Module): |
定义损失函数
1 | # 交叉熵损失函数 |
1 | loss2 = nn.CrossEntropyLoss() |
定义优化算法
1 | net = Net() |
1 | net2 = Net2() |
训练模型
1 | # 计算准确率 |
1 | def train(net, trainIter, testIter, loss, numEpochs, batchSize, |
Net模型训练
1 | train(net, trainIter, testIter, loss, numEpochs, batchSize,optimizer) |
epoch 1, loss 0.0128, train acc 0.667, test acc 0.667
epoch 2, loss 0.0118, train acc 0.683, test acc 0.760
epoch 3, loss 0.0104, train acc 0.742, test acc 0.807
epoch 4, loss 0.0093, train acc 0.769, test acc 0.772
epoch 5, loss 0.0085, train acc 0.797, test acc 0.745
epoch 6, loss 0.0084, train acc 0.798, test acc 0.807
epoch 7, loss 0.0082, train acc 0.804, test acc 0.816
epoch 8, loss 0.0078, train acc 0.816, test acc 0.812
epoch 9, loss 0.0077, train acc 0.818, test acc 0.817
epoch 10, loss 0.0074, train acc 0.824, test acc 0.826
epoch 11, loss 0.0072, train acc 0.836, test acc 0.819
epoch 12, loss 0.0075, train acc 0.823, test acc 0.829
epoch 13, loss 0.0071, train acc 0.839, test acc 0.797
epoch 14, loss 0.0067, train acc 0.849, test acc 0.824
epoch 15, loss 0.0069, train acc 0.848, test acc 0.843
epoch 16, loss 0.0064, train acc 0.864, test acc 0.851
epoch 17, loss 0.0062, train acc 0.867, test acc 0.780
epoch 18, loss 0.0060, train acc 0.871, test acc 0.864
epoch 19, loss 0.0057, train acc 0.881, test acc 0.890
epoch 20, loss 0.0055, train acc 0.885, test acc 0.897
Net2模型训练
1 | # batchSize = 50 |
epoch 1, loss 0.0119, train acc 0.638, test acc 0.676
epoch 2, loss 0.0079, train acc 0.823, test acc 0.986
epoch 3, loss 0.0046, train acc 0.987, test acc 0.977
epoch 4, loss 0.0030, train acc 0.983, test acc 0.973
epoch 5, loss 0.0023, train acc 0.981, test acc 0.976
epoch 6, loss 0.0019, train acc 0.980, test acc 0.988
epoch 7, loss 0.0016, train acc 0.984, test acc 0.984
epoch 8, loss 0.0014, train acc 0.985, test acc 0.986
epoch 9, loss 0.0013, train acc 0.987, test acc 0.992
epoch 10, loss 0.0011, train acc 0.989, test acc 0.993
epoch 11, loss 0.0010, train acc 0.989, test acc 0.996
epoch 12, loss 0.0010, train acc 0.992, test acc 0.994
epoch 13, loss 0.0009, train acc 0.993, test acc 0.994
epoch 14, loss 0.0008, train acc 0.995, test acc 0.996
epoch 15, loss 0.0008, train acc 0.994, test acc 0.998
测试
1 | test = torch.Tensor([[[[0,0,0,0],[0,1,1,0],[0,1,1,0],[0,0,0,0]]], |
1 | test |
tensor([[[[0., 0., 0., 0.],
[0., 1., 1., 0.],
[0., 1., 1., 0.],
[0., 0., 0., 0.]]],
[[[1., 1., 1., 1.],
[1., 0., 0., 1.],
[1., 0., 0., 1.],
[1., 1., 1., 1.]]],
[[[0., 1., 0., 1.],
[1., 0., 0., 1.],
[1., 0., 0., 1.],
[0., 0., 0., 1.]]],
[[[0., 1., 1., 1.],
[1., 0., 0., 1.],
[1., 0., 0., 1.],
[0., 0., 0., 1.]]],
[[[0., 0., 1., 1.],
[1., 0., 0., 1.],
[1., 0., 0., 1.],
[1., 0., 1., 0.]]],
[[[0., 0., 1., 0.],
[0., 1., 0., 1.],
[0., 0., 1., 1.],
[1., 0., 1., 0.]]],
[[[1., 1., 1., 0.],
[1., 0., 0., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.]]]])
1 | with torch.no_grad(): |
1 | # 比较结果 |
Net测试结果tensor([ True, True, False, True, True, True, True])
Net2测试结果tensor([False, True, False, True, True, False, True])